package com.ethink.warehouse.facade.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ethink.component.warehouse.WarehouseClient;
import com.ethink.component.warehouse.WarehouseInter;
import com.ethink.component.warehouse.enums.EtonbaoServiceNameEnum;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.framework.common.util.JacksonUtils;
import com.ethink.warehouse.api.WarehouseOpenapiFacade;
import com.ethink.warehouse.api.component.request.WarehouseCheckSignatureRequest;
import com.ethink.warehouse.api.component.request.WarehouseEtonbaoConfirmInStockRequest;
import com.ethink.warehouse.api.component.request.WarehouseEtonbaoCallbackRequest;
import com.ethink.warehouse.api.component.request.WarehouseEtonbaoConfirmOutStockRequest;
import com.ethink.warehouse.api.component.response.WarehouseEtonbaoCallbackResponse;
import com.ethink.warehouse.common.entity.LogisticsTraceOrder;
import com.ethink.warehouse.common.entity.StockInOrder;
import com.ethink.warehouse.common.entity.StockOutOrder;
import com.ethink.warehouse.common.mapper.LogisticsTraceOrderMapper;
import com.ethink.warehouse.common.mapper.StockInOrderMapper;
import com.ethink.warehouse.common.mapper.StockOutOrderMapper;
import com.ethink.warehouse.service.LogisticsTraceOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

/**
 * 仓库开放平台 Facade接口实现
 *
 * @author default
 * @date 2022-11-01
 */
@RestController
@Slf4j
@RequestMapping("warehouse-service/facade/v1/warehouseOpenapi")
public class WarehouseOpenapiFacadeImpl implements WarehouseOpenapiFacade {
    @Autowired
    private WarehouseClient warehouseClient;
    @Autowired
    private LogisticsTraceOrderService logisticsTraceOrderService;
    @Autowired
    private StockInOrderMapper stockInOrderMapper;
    @Autowired
    private StockOutOrderMapper stockOutOrderMapper;
    @Autowired
    private LogisticsTraceOrderMapper logisticsTraceOrderMapper;

    @Override
    public WarehouseEtonbaoCallbackResponse etonbaoCallback(WarehouseEtonbaoCallbackRequest request) {
        // 验签
        WarehouseCheckSignatureRequest checkSignatureRequest = new WarehouseCheckSignatureRequest();
        checkSignatureRequest.setAppKey(request.getApp_key());
        checkSignatureRequest.setSign(request.getSign());
        Map<String, String> signParams = new HashMap<>();
        signParams.put("app_key", request.getApp_key());
        signParams.put("name", request.getName());
        signParams.put("timestamp", request.getTimestamp());
        signParams.put("data", request.getData());
        checkSignatureRequest.setSignParams(signParams);

        EtonbaoServiceNameEnum etonbaoServiceName = EtonbaoServiceNameEnum.valueOfCode(request.getName());
        if (etonbaoServiceName == null) {
            return etonbaoCallbackFailed("无法识别接口！");
        }
        String bizJsonData;
        try {
            bizJsonData = URLDecoder.decode(request.getData(), "UTF-8");
        }  catch (UnsupportedEncodingException e) {
            return etonbaoCallbackFailed("业务数据解码失败！");
        }
        log.info("青岛仓回调：{}", bizJsonData);
        if (etonbaoServiceName.equals(EtonbaoServiceNameEnum.ENTRYORDER_CONFIRM)) {
            // 入库单确认
            WarehouseEtonbaoConfirmInStockRequest confirmInStockRequest = JacksonUtils.toObj(bizJsonData, WarehouseEtonbaoConfirmInStockRequest.class);

            StockInOrder stockInOrder = stockInOrderMapper.selectOne(
                    new LambdaQueryWrapper<StockInOrder>()
                            .eq(StockInOrder::getOutOrderNo, confirmInStockRequest.getEntryOrder().getEntryOrderId())
                            .eq(StockInOrder::getIsDeleted, false)
            );
            if (stockInOrder == null) {
                return etonbaoCallbackFailed("入库单ID无效！");
            }
            LogisticsTraceOrder logisticsTraceOrder = logisticsTraceOrderMapper.selectOne(
                    new LambdaQueryWrapper<LogisticsTraceOrder>()
                            .eq(LogisticsTraceOrder::getOrderNo, stockInOrder.getOrderNo())
                            .eq(LogisticsTraceOrder::getIsDeleted, false)
            );
            if (logisticsTraceOrder == null) {
                return etonbaoCallbackFailed("未查询到对应业务单据！");
            }

            WarehouseInter warehouseInter = warehouseClient.getWarehouseService(logisticsTraceOrder.getTargetWarehouseCode());
            if (!warehouseInter.checkSignature(checkSignatureRequest)) {
                return etonbaoCallbackFailed("验签不通过！");
            }

            try {
                logisticsTraceOrderService.etonbaoInStockConfirm(confirmInStockRequest);
                return etonbaoCallbackSucceed();
            } catch (BusinessException e) {
                return etonbaoCallbackFailed(e.getCodeMessage());
            } catch (Exception e) {
                e.printStackTrace();
                return etonbaoCallbackFailed("业务处理失败！");
            }
        } else if (etonbaoServiceName.equals(EtonbaoServiceNameEnum.STOCKOUT_CONFIRM)) {
            // 出库单确认
            WarehouseEtonbaoConfirmOutStockRequest confirmOutStockRequest = JacksonUtils.toObj(bizJsonData, WarehouseEtonbaoConfirmOutStockRequest.class);

            StockOutOrder stockOutOrder = stockOutOrderMapper.selectOne(
                    new LambdaQueryWrapper<StockOutOrder>()
                            .eq(StockOutOrder::getOutOrderNo, confirmOutStockRequest.getDeliveryOrder().getDeliveryOrderId())
                            .eq(StockOutOrder::getIsDeleted, false)
            );
            if (stockOutOrder == null) {
                return etonbaoCallbackFailed("出库单ID无效！");
            }
            LogisticsTraceOrder logisticsTraceOrder = logisticsTraceOrderMapper.selectOne(
                    new LambdaQueryWrapper<LogisticsTraceOrder>()
                            .eq(LogisticsTraceOrder::getOrderNo, stockOutOrder.getOrderNo())
                            .eq(LogisticsTraceOrder::getIsDeleted, false)
            );
            if (logisticsTraceOrder == null) {
                return etonbaoCallbackFailed("未查询到对应业务单据！");
            }

            WarehouseInter warehouseInter = warehouseClient.getWarehouseService(logisticsTraceOrder.getSourceWarehouseCode());
            if (!warehouseInter.checkSignature(checkSignatureRequest)) {
                return etonbaoCallbackFailed("验签不通过！");
            }

            try {
                logisticsTraceOrderService.etonbaoOutStockConfirm(confirmOutStockRequest);
                return etonbaoCallbackSucceed();
            } catch (BusinessException e) {
                return etonbaoCallbackFailed(e.getCodeMessage());
            } catch (Exception e) {
                e.printStackTrace();
                return etonbaoCallbackFailed("业务处理失败！");
            }
        } else {
            return etonbaoCallbackFailed("业务暂时未涉及！");
        }
    }

    private WarehouseEtonbaoCallbackResponse etonbaoCallbackSucceed() {
        WarehouseEtonbaoCallbackResponse response = new WarehouseEtonbaoCallbackResponse();
        response.setCode("0");
        response.setMsg("");
        response.setSuccess(true);
        return response;
    }

    private WarehouseEtonbaoCallbackResponse etonbaoCallbackFailed(String msg) {
        WarehouseEtonbaoCallbackResponse response = new WarehouseEtonbaoCallbackResponse();
        response.setCode("1");
        response.setMsg(msg);
        response.setSuccess(false);
        return response;
    }
}